package com.yunxi.service.dubboService.impl.sto;

import com.alibaba.cloud.context.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageInfo;
import com.yunxi.bizToHub.pojo.DespatchOrderAuditVO;
import com.yunxi.bizToHub.service.DespatchOrderDubboService;
import com.yunxi.core.base.Constant;
import com.yunxi.core.enums.DMSEnumsEntity;
import com.yunxi.core.web.DictConstant;
import com.yunxi.model.order.OrderVehicle;
import com.yunxi.model.order.PmsVehicleStock;
import com.yunxi.model.sto.*;
import com.yunxi.order.service.OrderCustomerDubboService;
import com.yunxi.order.service.OrderOemManagerDubboService;
import com.yunxi.order.service.OrderVehicleDubboService;
import com.yunxi.sat.pojo.SatMessAddVO;
import com.yunxi.service.localService.OrderVehicleService;
import com.yunxi.service.localService.sat.SatMessService;
import com.yunxi.service.localService.sto.*;
import com.yunxi.sto.pojo.*;
import com.yunxi.sto.service.StoStockOutPlanDubboService;
import com.yunxi.sto.service.StoTransportOrderDubboService;
import com.yunxi.sto.service.VehiclePdiBillDubboService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import java.lang.reflect.InvocationTargetException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 车辆发运单 服务实现类
 * </p>
 *
 * @author caoYong
 * @since 2019-05-29
 */
public class StoTransportOrderDubboServiceImpl implements StoTransportOrderDubboService {

    @Autowired
    @Qualifier(value = "stoTransportOrderServiceImpl")
    StoTransportOrderService stoTransportOrderService;

    @Autowired
    @Qualifier(value = "stoTransportOrderDetailServiceImpl")
    StoTransportOrderDetailService stoTransportOrderDetailService;

    @Autowired
    @Qualifier(value = "orderOemManagerDubboServiceImpl")
    OrderOemManagerDubboService orderOemManagerDubboService;

    @Autowired
    @Qualifier(value = "despatchOrderDubboServiceI")
    DespatchOrderDubboService despatchOrderDubboService;

    @Autowired
    @Qualifier(value = "stoCarrierServiceImpl")
    StoCarrierService stoCarrierService;

    @Autowired
    @Qualifier(value = "stoStockOutPlanDubboServiceImpl")
    StoStockOutPlanDubboService stoStockOutPlanDubboService;

    @Autowired
    @Qualifier(value = "vehiclePdiBillServiceImpl")
    VehiclePdiBillService vehiclePdiBillService;

    @Autowired
    @Qualifier(value = "vehicleStockMServiceImpl")
    VehicleStockMService vehicleStockMService;

    @Autowired
    @Qualifier(value = "vehicleOfflineServiceImpl")
    VehicleOfflineService vehicleOfflineService;

    @Autowired
    @Qualifier(value = "orderVehicleServiceImpl")
    OrderVehicleService orderVehicleService;

    @Autowired
    @Qualifier(value = "orderVehicleDubboServiceImpl")
    OrderVehicleDubboService orderVehicleDubboService;

    @Autowired
    @Qualifier(value = "satMessServiceImpl")
    SatMessService satMessService;

    @Autowired
    @Qualifier(value = "stoVehicleDeliveryServiceImpl")
    StoVehicleDeliveryService stoVehicleDeliveryService;

    @Autowired
    OrderCustomerDubboService orderCustomerDubboServiceImpl;

    @Autowired
    VehiclePdiBillDubboService vehiclePdiBillDubboService;


    @Value("${TMS.URL02}")
    private String tmsUrl02;


    @Override
    public StoTransportOrderVO getById(String id)throws Exception{
        StoTransportOrderVO vo = stoTransportOrderService.getDetailById(id);
        if(vo == null)throw new Exception("操作失败,无法根据主键:找到对应运单详情!");
        return vo;
    }

    @Override
    public void saveOrUpdate(StoTransportOrderVO stoTransportOrderVO)  {
        StoTransportOrder stoTransportOrder = new StoTransportOrder();
        BeanUtils.copyProperties(stoTransportOrderVO, stoTransportOrder);
        stoTransportOrderService.saveOrUpdate(stoTransportOrder);
    }

    @Override
    public void removeById(String id) {
    stoTransportOrderService.removeById(id);
    }

    /**
     * 发运单分页查询
     * @param stoTransportOrderVO
     * @param pageNum
     * @param pageSize
     * @return
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    @Override
    public PageInfo<StoTransportOrderVO> findPageByVO(StoTransportOrderVO stoTransportOrderVO, Integer pageNum, Integer pageSize) {
        PageInfo<StoTransportOrderVO> pageInfo = stoTransportOrderService.pageByVo(stoTransportOrderVO, pageNum, pageSize);
        return pageInfo;
    }

    /**
     * 发运单明细分页查询
     * @param stoTransportOrderDetailVO
     * @param pageNum
     * @param pageSize
     * @return
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    @Override
    public PageInfo<StoTransportOrderDetailVO> detailPage(StoTransportOrderDetailVO stoTransportOrderDetailVO, Integer pageNum, Integer pageSize) {
        PageInfo pageInfo = stoTransportOrderDetailService.pageByVo(stoTransportOrderDetailVO, pageNum, pageSize);
       List<StoTransportOrderDetailVO> list  = pageInfo.getList();
        //如果没有经纬度  默认设置经纬度为 上饶工厂
       for(StoTransportOrderDetailVO transportOrderDetailVO :list){
           if(StringUtils.isEmpty(transportOrderDetailVO.getLat())){
               transportOrderDetailVO.setLat(Constant.PMS_LAT);
           }
           if(StringUtils.isEmpty(transportOrderDetailVO.getLng())){
               transportOrderDetailVO.setLng(Constant.PMS_LNG);
           }
       }
        return pageInfo;
    }

    @Override
    public void removeByListVo(List<StoTransportOrderVO> stoTransportOrderVOList) throws IllegalAccessException, InvocationTargetException, InstantiationException {
        stoTransportOrderService.removeByListVo(stoTransportOrderVOList);
    }

    /**
     * 批量确认收车
     * @param list
     * @throws Exception
     */
    @Override
    public void receive(List<String> list,String partnerCode,String userName,String userCode) throws Exception {
        if (list != null && list.size() > 0) {
            for (String id : list) {
                StoTransportOrder byId = stoTransportOrderService.getById(id);
                if (byId != null) {
                    Integer orderState = byId.getOrderState();
                    if (orderState != null && (orderState.equals(3) || orderState.equals(4))) {
                        throw new Exception("操作失败,已确认收车不可再次收车!");
                    }
                    else if(orderState != null && !orderState.equals(2)){
                        throw new Exception("操作失败,未发运不可接车!");
                    }
                    byId.setOrderState(3);//运单状态 全部接车
                    byId.setVehicleReceiveTime(new Date());//接车时间
                    byId.setReceiverName(userName);
                    String phone = stoTransportOrderService.queryPhoneByUserCode(userCode);
                    if(StringUtils.isNotEmpty(phone)){
                        byId.setReceiverPhone(phone);
                    }
                    stoTransportOrderService.updateById(byId);

                    //渠道收车,推送信息到订单
                    pushReceiveVehicelToOrder(id);
                    //更新车辆流转状态为渠道收车
                    updateVehicleOwner(partnerCode, byId);
                    //渠道收车推送APP
                    QueryWrapper<StoTransportOrderDetail> queryWrapper = new QueryWrapper<>();
                    queryWrapper.eq("TRANSPORT_ORDER_NO",byId.getTransportOrderNo());
                    List<StoTransportOrderDetail> list1 = stoTransportOrderDetailService.list(queryWrapper);
                    if(list1 != null && list1.size() > 0){
                        for(StoTransportOrderDetail bo : list1){
                            vehiclePdiBillDubboService.sentMsgToApp(bo.getVin(),DictConstant.APP_RPNAME_VDC_PRECEIVE,DictConstant.APP_CODE_05);
                        }
                    }
                } else {
                    throw new Exception("操作失败,无法根据主键id:" + id + "找到对应发运单!");
                }
            }
        }
    }

    /**
     * 设置车辆所属渠道商
     * @param partnerCode
     * @param byId
     */
    private void updateVehicleOwner(String partnerCode, StoTransportOrder byId) {
        QueryWrapper<StoTransportOrderDetail> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("TRANSPORT_ORDER_NO",byId.getTransportOrderNo());
        List<StoTransportOrderDetail> list1 = stoTransportOrderDetailService.list(queryWrapper);
        if(list1 != null && list1.size() > 0){
            for(StoTransportOrderDetail sto : list1){
                //更新车辆流转状态为渠道收车
                QueryWrapper<VehicleOffline> queryWrapper2 = new QueryWrapper<>();
                queryWrapper2.eq("VIN",sto.getVin());
                VehicleOffline vehicleOffline = vehicleOfflineService.getOne(queryWrapper2);
                if(vehicleOffline != null){
                    String carState = vehicleOffline.getCarState();
                    if(StringUtils.isEmpty(carState) || !carState.equals(DictConstant.VEHICLE_TURN_STATE_13QDSC)){
                        vehicleOffline.setCarState(DictConstant.VEHICLE_TURN_STATE_13QDSC);
                        vehicleOfflineService.saveOrUpdate(vehicleOffline);
                    }
                }
            }
        }
    }

    /**
     * 发运单审批
     * @param stoTransportOrderApproveVO
     * @throws Exception
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void approve(StoTransportOrderApproveVO stoTransportOrderApproveVO) throws Exception {
        List<String> idList = stoTransportOrderApproveVO.getTransportOrderIdList();
        if(idList == null || idList.size() <= 0)throw new Exception("操作失败,主键id集合为空!");
        List<DespatchOrderAuditVO> list = new ArrayList<>();
        for (String id :idList){
            StoTransportOrder stoTransportOrder = stoTransportOrderService.getById(id);
            if(stoTransportOrder == null)throw new Exception("操作失败,无法根据id:"+id+"找到对应运单记录!");
            stoTransportOrder.setApproveStatus(stoTransportOrderApproveVO.getApproveStatus());
            stoTransportOrder.setApproveRemark(stoTransportOrderApproveVO.getApproveRemark());
            //1.更新发运单状态
            stoTransportOrderService.saveOrUpdate(stoTransportOrder);

            //2.PMS推送审批结果到TMS
            DespatchOrderAuditVO despatchOrderAuditVO = new DespatchOrderAuditVO();
            despatchOrderAuditVO.setCarrierCode(stoTransportOrder.getCarrierCode());//承运商代码
            despatchOrderAuditVO.setCarrierName(stoTransportOrder.getCarrierName());//承运商名称
            despatchOrderAuditVO.setLoadCode(stoTransportOrder.getTransportOrderNo());//发运单号
            despatchOrderAuditVO.setStatue(stoTransportOrder.getApproveStatus().toString());//审批结果
            despatchOrderAuditVO.setApproveComment(stoTransportOrder.getApproveRemark());//审批意见
            //承运商URL
//            QueryWrapper<StoCarrier> queryWrapper = new QueryWrapper<>();
//            queryWrapper.eq("CARRIER_CODE",stoTransportOrder.getCarrierCode());
//            StoCarrier stoCarrier = stoCarrierService.getOne(queryWrapper);
//            if(stoCarrier != null)despatchOrderAuditVO.setUrl(stoCarrier.getTmsUrl());
            despatchOrderAuditVO.setUrl(tmsUrl02);
            list.add(despatchOrderAuditVO);

            //3. 审批通过生成出库计划
            if (stoTransportOrderApproveVO.getApproveStatus() == 0) {
                addStockOutPlan(stoTransportOrder);
            }
        }
        //2.PMS推送审批结果到TMS
        despatchOrderDubboService.despatchOrderAuditPms2Tms(list);
    }

    /**
     * 入库
     * @param stoTransportOrderStockInVO
     * @throws Exception
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void stockIn(StoTransportOrderStockInVO stoTransportOrderStockInVO) throws Exception {
        StoTransportOrderDetail stoTransportOrderDetail = stoTransportOrderDetailService.getById(stoTransportOrderStockInVO.getTransportOrderDetailId());
        if(stoTransportOrderDetail == null)throw new Exception("操作失败,无法根据主键ID:找到对应记录!");
        Integer isStockIn = stoTransportOrderDetail.getIsStockIn();
        if(isStockIn.equals(1))throw new Exception("操作失败,已入库不可再次入库!");
        //检查运单状态是否签收
        checkOrderState(stoTransportOrderDetail);
        stoTransportOrderDetail.setIsStockIn(1);
        stoTransportOrderDetail.setStockInUser(stoTransportOrderStockInVO.getStockInUser());
        stoTransportOrderDetail.setStockInDate(new Date());
        stoTransportOrderDetail.setPdiPicPath(stoTransportOrderStockInVO.getPdiPicPath());
        //1.更新运单详情为已接车
        stoTransportOrderDetailService.saveOrUpdate(stoTransportOrderDetail);
        //2.设置库存车辆partner_code
        QueryWrapper<PmsVehicleStock> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq("VIN",stoTransportOrderDetail.getVin());
        PmsVehicleStock vehicleStock = vehicleStockMService.getOne(queryWrapper1);
        if(vehicleStock != null){
            // 查询经销商仓库
            LambdaQueryWrapper<OrderVehicle> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(OrderVehicle::getVin, stoTransportOrderDetail.getVin());
            OrderVehicle orderVehicle = orderVehicleService.getOne(lambdaQueryWrapper);
            vehicleStock.setStorageCode(orderVehicle.getStorageCode());
            vehicleStock.setStorageLocation("");

            vehicleStock.setPartnerCode(stoTransportOrderStockInVO.getPartnerCode());
            vehicleStock.setStorageStatus(1);//在渠道商库
            vehicleStock.setInStockDate(new Date());//入库日期
            //update 20190923 店端入库后,清空车辆仓库信息
//            vehicleStock.setStorageCode(null);
//            vehicleStock.setStorageLocation(null);
            vehicleStockMService.saveOrUpdate(vehicleStock);
        }
        //3.设置车辆流转状态为渠道入库
        QueryWrapper<VehicleOffline> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("VIN",stoTransportOrderDetail.getVin());
        VehicleOffline vehicleOffline = vehicleOfflineService.getOne(queryWrapper);
        if(vehicleOffline != null){
            vehicleOffline.setStorageStatus(DictConstant.VEHICLE_IN_STOCK);
            vehicleOffline.setIsLock(Constant.PMS_VEHICLE_IS_NOT_LOCK);
            vehicleOffline.setCarState(DictConstant.VEHICLE_TURN_STATE_14QDRK);
            vehicleOfflineService.saveOrUpdate(vehicleOffline);
        }

        //4.入库完成更新VIN到零售订单
        orderCustomerDubboServiceImpl.updateVin(stoTransportOrderDetail.getVin());

        //5.渠道入库推送APP
        vehiclePdiBillDubboService.sentMsgToApp(stoTransportOrderDetail.getVin(),DictConstant.APP_RPNAME_VDC_PIN,DictConstant.APP_CODE_06);

        //6.体验车/试驾车 入库生成实销数据
        orderVehicleDubboService.createDataForExpience(stoTransportOrderDetail.getVin());

        //7.更新车辆订单状态为入库
        orderOemManagerDubboService.updateOrderVehicleStatusByVin(stoTransportOrderDetail.getVin(), Constant.PMS_ORDER_VEHICLE_CHECK_STATUS_DEALER_INSTOCK);

    }

    /**
     * 检查运单状态是否签收
     * @param stoTransportOrderDetail
     * @throws Exception
     */
    private void checkOrderState(StoTransportOrderDetail stoTransportOrderDetail) throws Exception {
        String transportOrderNo = stoTransportOrderDetail.getTransportOrderNo();
        QueryWrapper<StoTransportOrder> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.eq("TRANSPORT_ORDER_NO",transportOrderNo);
        StoTransportOrder stoTransportOrder = stoTransportOrderService.getOne(queryWrapper2);
        if(stoTransportOrder != null){
            Integer orderState = stoTransportOrder.getOrderState();
            //  一车一单取消部分配车
//            if(orderState == null ||!orderState.equals(3) || !orderState.equals(4)){
            if (orderState == null || !orderState.equals(3)) {
                throw new Exception("操作失败,需要先签收运单才能进行入库!");
            }
        }
    }


    /**
     * 渠道收车,推送信息到订单
     * @param id
     */
    private void pushReceiveVehicelToOrder(String id) {
        List<StoTransportOrderDetail> vinList = stoTransportOrderService.queryVinListByOrderId(id);
        if(vinList != null && vinList.size() > 0){
            for (StoTransportOrderDetail stoTransportOrderDetail : vinList){
                String vin = stoTransportOrderDetail.getVin();
                orderOemManagerDubboService.updateOrderVehicleStatusByVin(vin, Constant.PMS_ORDER_VEHICLE_CHECK_STATUS_DEALER_CONFIRM);
            }
        }
    }

    /**
     * 生成出库计划
     * @param stoTransportOrder
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    private void addStockOutPlan(StoTransportOrder stoTransportOrder) throws Exception {
        String transportOrderNo = stoTransportOrder.getTransportOrderNo();
        QueryWrapper<StoTransportOrderDetail> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq("TRANSPORT_ORDER_NO",transportOrderNo);
        List<StoTransportOrderDetail> list1 = stoTransportOrderDetailService.list(queryWrapper1);
        if(list1 != null && list1.size() > 0){
            for (StoTransportOrderDetail bo : list1){
                StoStockOutPlanVO stoStockOutPlanVO = new StoStockOutPlanVO();
                stoStockOutPlanVO.setVin(bo.getVin());
                stoStockOutPlanVO.setBillState("1");
                stoStockOutPlanVO.setPlanStockOutDate(stoTransportOrder.getPlanArrivedTime());
                stoStockOutPlanVO.setTransportOrderNo(transportOrderNo);
                stoStockOutPlanVO.setShippingRoad(stoTransportOrder.getShippingRoad());
                //1.查询今日上班司机,取今日出入库次数和最少的一位司机
                Date date = new Date();
                SimpleDateFormat dd = new SimpleDateFormat("dd");
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                String day = dd.format(date);
                String dayStr = String.valueOf(Integer.parseInt(day));
                String format = simpleDateFormat.format(date);
                StoDriverVO stoDriverVO1 = new StoDriverVO();
                stoDriverVO1.setDay(Integer.parseInt(day));
                stoDriverVO1.setWorkMonth(format);
                List<StoDriverVO> list4 = vehiclePdiBillService.queryTodayDriver(stoDriverVO1);
                if(list4 != null && list4.size() > 0){
                    for (StoDriverVO vo : list4){
                        String workDays = vo.getWorkDays();
                        if(StringUtils.isNotEmpty(workDays)){
                            String[] split = workDays.split(",");
                            Boolean isContains = false;
                            for(String workDay : split){
                                if(workDay.equals(dayStr)){
                                    isContains = true;
                                    break;
                                }
                            }
                            if(isContains){
                                stoStockOutPlanVO.setStockOutDriver(vo.getRfid());
                                stoStockOutPlanVO.setRfidDate(new Date());

                                //推送消息给司机
                                SatMessAddVO satMessAddVO = new SatMessAddVO();
                                satMessAddVO.setType("出库");
                                satMessAddVO.setInfo("有一个新的出库计划!");
                                satMessAddVO.setSalesConsultantNo(vo.getUserCode());
                                satMessAddVO.setReceiveRoleCode(DictConstant.USER_ROLE_DRIVER);
                                satMessService.pdaNewMess(satMessAddVO);
                            }
                        }
                    }
                }
                stoStockOutPlanVO.setStockOutType("1");
                //通过VIN码查询批售单付款类型,现金则合格证随车,非现金则合格证不随车
                QueryWrapper<OrderVehicle> queryWrapper2 = new QueryWrapper<>();
                queryWrapper2.eq("VIN",bo.getVin());
                List<OrderVehicle> list = orderVehicleService.list(queryWrapper2);
                Integer isOnVehicle = null;
                if(list != null && list .size() > 0){
                    OrderVehicle orderVehicle = list.get(0);
                    String payway = orderVehicle.getPayway();
                    if(StringUtils.isNotEmpty(payway) && payway.equals(DMSEnumsEntity.PaywayType.CASH.getKey())){
                        isOnVehicle = 1;
                    }
                    else {
                        isOnVehicle = 0;
                    }
                }
                if(isOnVehicle != null){
                    stoStockOutPlanVO.setIsOnVehicle(isOnVehicle);
                }
                //根据VIN码查询整车外向交货单号
                QueryWrapper<StoVehicleDelivery> queryWrapper3 = new QueryWrapper<>();
                queryWrapper3.eq("VHVIN",bo.getVin());
                StoVehicleDelivery stoVehicleDelivery = stoVehicleDeliveryService.getOne(queryWrapper3);
                if(stoVehicleDelivery != null){
                    stoStockOutPlanVO.setDeliveryNo(stoVehicleDelivery.getVbeln());//交货单号
                }
                try{
                    stoStockOutPlanDubboService.saveOrUpdate(stoStockOutPlanVO);
                }
                catch (Exception e){
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    throw new Exception(e);
                }
            }
        }
    }
}
